package com.wewins.fota.service;

import com.alibaba.fastjson.JSON;
import com.wewins.fota.bean.bo.DownloadReq;
import com.wewins.fota.bean.bo.ServerInfo;
import com.wewins.fota.bean.bo.UploadFile;
import com.wewins.fota.bean.dto.ResponseRst;
import com.wewins.fota.bean.po.FotaLog;
import com.wewins.fota.constant.FotaConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.Duration;
import java.util.UUID;

@Slf4j
@Service
public class FotaVersionService {
    private static final int LOG_OPERATE_DOWNLOAD = 2;

    private final RedisTemplate<String, String> template;

    @Value("${fota.file-timeout:10m}")
    private Duration fileTimeout;

    private final ServerInfo serverInfo;

    @Autowired
    public FotaVersionService(RedisTemplate<String, String> template, ServerInfo serverInfo) {
        this.template = template;
        this.serverInfo = serverInfo;
    }

    public ResponseRst<String> upload(MultipartFile file, String product) {
        ResponseRst<String> res = ResponseRst.<String>builder().build().withOk();
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            fileName = UUID.randomUUID().toString().replace("-", "");
        }
        File f = new File(serverInfo.getSourcePath(), product);
        if (!f.exists()) {
            f.mkdirs();
        }
        File dstFile = new File(f, fileName);
        if (dstFile.exists()) {
            int index = fileName.lastIndexOf(".");
            fileName = fileName.substring(0, index) + "_" + System.currentTimeMillis() + fileName.substring(index);
            dstFile = new File(f, fileName);
        }
        try {
            file.transferTo(dstFile);
            res.setData("http://" + serverInfo.getDomain() + serverInfo.getContextPath() + "/download/" + product + "/" + fileName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            res.withError(FotaConst.STATUS_ERROR, e.getMessage());
        } finally {
            UploadFile uploadFile = UploadFile.builder()
                    .serverKey(serverInfo.getKey())
                    .path(dstFile.getAbsolutePath())
                    .uploadTime(System.currentTimeMillis() + fileTimeout.toMillis())
                    .build();
            template.opsForHash().put(
                    FotaConst.REDIS_KEY_INVALID_FILE,
                    String.format("%s:%s", product, fileName),
                    JSON.toJSONString(uploadFile)
            );
        }
        return res;
    }

    public int writeLog(DownloadReq req) {
        FotaLog fotaLog = FotaLog.builder()
                .product(req.getProduct())
                .imei(req.getImei())
                .reqServer(req.getReqServer())
                .respServer(req.getRespServer())
                .operator(LOG_OPERATE_DOWNLOAD)
                .autoDownload(req.getAutoDownload())
                .fromV(req.getSrcVersion())
                .toV(req.getDstVersion())
                .createTime(System.currentTimeMillis())
                .count(1)
                .build();
        this.template.opsForList().leftPush(FotaConst.REDIS_KEY_LOG_LIST, JSON.toJSONString(fotaLog));
        return FotaConst.STATUS_SUCCESS;
    }

    public File loadFile(String relativePath, String fileName) {
        return new File(serverInfo.getSourcePath(), relativePath + File.separator + fileName);
    }
}
